package tools

import (
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

const TokenExpire = 14 * 24 * time.Hour

const TypePhone = 1      // 手机号登录
const TypeAccount = 2    // 账号&邮箱登录 后台登录
const TypeSnoAccount = 3 // 学号登录

const ThemeTopicDefault = "default" // 默认皮肤
const ThemeTopicBeida = "beida"     // 北大红

// 定义秘钥
var jwtKey = []byte("beijingzhipuhuazhang")

type Claims struct {
	UserId uint
	Phone  string
	Code   string
	Env    string
	Type   int // 用户登录服务
	St     interface{}
	jwt.StandardClaims
}

type Sto struct {
	Id          uint
	AgentId     uint
	RoleId      uint
	Phone       string
	Type        string
	School      string
	Sno         string
	AccountName string
	ThemeTopic  string // 前端页面的主题 红色 或者 紫色
	Source      string // 来源标记（盒子和第三方登录标记）
}

// 登录成功之后发放token
func GenToken(ctx *gin.Context, phone string, code string, user_id uint, env string, typ int, st interface{}) (string, error) {
	expirationTime := time.Now().Add(TokenExpire) //token的有效期是14天
	claimType := typ
	if typ == 0 {
		claimType = TypePhone
	}
	claims := &Claims{
		UserId: user_id,
		Phone:  phone,
		Code:   code,
		Env:    env,
		Type:   claimType,
		St:     st,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expirationTime.Unix(), //token的有效期
			IssuedAt:  time.Now().Unix(),     //token发放的时间
			Issuer:    "suqichang",           //作者
			Subject:   "user token",          //主题
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString(jwtKey) //根据前面自定义的jwt秘钥生成token

	if err != nil {
		return "", err
	}
	//返回成功生成的字符换
	return tokenString, nil
}

//eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjYsImV4cCI6MTYzNzY2Nzk5OCwiaWF0IjoxNjM3MDYzMTk4LCJpc3MiOiJjaGVuZ3FpYW5nIiwic3ViIjoidXNlciB0b2tlbiJ9.nt8K7vxrAT4XXzh0RbtFveQCyt7J4r1XZnVgDNSVjkQ
//token由三部分组成
//加密协议、荷载（程序信息）、前面两部分+自定义密匙组成的一个哈希值
//使用base64解密保存的信息(分三段进行解密) ：  echo eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 | base64 -D

// 解析从前端获取到的token值
func ParseToken(tokenString string) (*jwt.Token, *Claims, error) {
	claims := &Claims{}
	token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
		return jwtKey, nil
	})
	return token, claims, err
}
